﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace RQX.Common.Web.Web.Container
{
    public class ApolloPlug
    {
        private static ConcurrentDictionary<string, Type> ClassDic = new ConcurrentDictionary<string, Type>();
        //private static ConcurrentDictionary<string, Type> DbContextDic = new ConcurrentDictionary<string, Type>();

        private readonly Assembly _assembly = null;
        //private readonly string _dbContextName = null;

        public ApolloPlug(Assembly assembly)
        {
            _assembly = assembly;
            //_dbContextName = dbContextName;
        }

        public ApolloPlugClass GetClass(string className)
        {
            var classType = GetClassType(className);
            if (classType == null) return null;

            var parameters = classType.GetConstructors()?[0]?.GetParameters();
            List<Type> constructorTypes = new List<Type>();
            foreach (var param in parameters)
            {
                var type = GetClassType(param.ParameterType.Name);
                constructorTypes.Add(type);
            }

            return new ApolloPlugClass(this, classType, constructorTypes);
        }

        private Type GetClassType(string className)
        {
            var key = $"{_assembly.GetName().Name}-{className}";
            ClassDic.TryGetValue(key, out Type classType);
            if (classType == null)
            {
                classType = _assembly.GetTypes().Where(k => k.Name.Equals(className)).FirstOrDefault();
                if (classType != null) ClassDic.TryAdd(key, classType);
            }
            return classType;
        }

        //private Type GetDbType()
        //{
        //    var key = $"{_assembly.GetName().Name}-{_dbContextName}";
        //    DbContextDic.TryGetValue(_dbContextName, out Type dbType);
        //    if(dbType == null)
        //    {
        //        dbType =  _assembly.GetTypes().Where(k => k.Name.Equals(_dbContextName)).FirstOrDefault();
        //        if (dbType != null) DbContextDic.TryAdd(key, dbType);
        //    }
        //    return dbType;
        //}

    }
}
